package jp.seraph.jsade.core;

import java.util.List;

import org.apache.commons.math.geometry.Vector3D;

import jp.seraph.jsade.model.ModelManager;
import jp.seraph.jsade.perceptor.GameState;
import jp.seraph.jsade.perceptor.HearPerceptor;
import jp.seraph.jsade.perceptor.PerceptorVisitor;
import jp.seraph.jsade.perceptor.SeeObject;
import jp.seraph.jsade.perceptor.SeeObjectType;

/**
 * エージェントが知覚可能な全情報を表すインターフェースです
 *
 *
 */
public interface World extends PerceptorVisitor {
    /**
     * モデルを管理するマネージャを返します。
     *
     * @return
     */
    ModelManager getModelManager();

    /**
     * エージェントのプレイヤー以外の視覚情報を返します。
     *
     * @param aType
     * @return
     */
    SeeObject getSeeObject(SeeObjectType aType);

    /**
     * エージェントの視覚情報のうちプレイヤーの情報を返します。
     *
     * @return
     */
    List<SeeObject> getSeePlayers();

    /**
     * エージェントの視覚情報のうち、ボールの情報を返します。
     *
     * @return
     */
    SeeObject getBall();

    /**
     * エージェントが受信したメッセージ列を返します。
     *
     * @return
     */
    List<HearPerceptor> getHears();

    /**
     * 現在のゲーム時間を返します。
     *
     * @return
     */
    double getTime();

    /**
     * 現在のゲームステートを返します。
     *
     * @return
     */
    GameState getGameState();

    /**
     * 現在のゲームステートになってからの時間を返します。
     *
     * @return
     */
    double getGameStateTime();

    /**
     * Worldに対して新しいターンの開始を通知する。
     * このメソッドはフレームワーク内で使用されることを想定しており、フレームワークを使用するユーザは呼び出すべきではない。
     */
    void setUpTurn();

    /**
     * Worldに対してターンの終了を通知する
     * このメソッドはフレームワーク内で使用されることを想定しており、フレームワークを使用するユーザは呼び出すべきではない。
     */
    void tearDownTurn();

    /**
     * エージェントの視界から見たフィールドのX方向単位ベクトル(Left -> Right)を返す
     * このメソッドは、エージェントの視界に制限がかかった場合使用できなくなります。
     *
     * @return
     */
    Vector3D getUnitVectorX();

    /**
     * エージェントの視界から見たフィールドのY方向単位ベクトル(手前 => 奥)を返す
     * このメソッドは、エージェントの視界に制限がかかった場合使用できなくなります。
     *
     * @return
     */
    Vector3D getUnitVectorY();

    /**
     * エージェントの視界から見たフィールドのZ方向単位ベクトルを返す
     * このメソッドは、エージェントの視界に制限がかかった場合使用できなくなります。
     *
     * @return
     */
    Vector3D getUnitVectorZ();
    
    /**
     * 敵ゴールの中心位置を指すベクトルを返します。
     * 
     * @return
     */
    Vector3D getOpponentGoalVector();
    
    /**
     * 自ゴールの中心位置を指すベクトルを返します。
     * @return
     */
    Vector3D getMyGoalVector();
    
    /**
     * 自フィールドから敵フィールドへの単位ベクトルを返します。
     * 自分がLeftチームである場合getUnitVectorXと同じになります。
     * 
     * @return
     */
    Vector3D getOpponentFieldUnitVector();
    
    /**
     * 敵フィールドから自フィールドへの単位ベクトルを返します。
     * 自分がRightチームである場合getUnitVectorXと同じになります。
     * 
     * @return
     */
    Vector3D getMyFieldUnitVector();

    /**
     * チーム情報を保持しているかどうか
     *
     * @see isLeft()
     * @see isRight()
     * @return 保持していればtrue
     */
    boolean hasTeam();

    /**
     * チームがLeft側であるかどうか
     * hasTeamがfalseであるとき、このメソッドの返り値は不定です。
     *
     * @see hasTeam()
     * @return Leftであればtrue
     */
    boolean isLeft();

    /**
     * チームがRight側であるかどうか
     * hasTeamがfalseであるとき、このメソッドの返り値は不定です。
     *
     * @see hasTeam()
     * @return Rightであればtrue
     */
    boolean isRight();
}
